package onlinebanking.network;

import org.json.*;

import onlinebanking.constants.*;

/**
 * The object that wraps a message that is sent/received to/from the network
 * core.
 * 
 * @author Edgar
 * 
 */
public class Message {

	private JSONObject jsonobject;

	private static final String TYPE = "TYPE";
	private static final String SUBTYPE = "SUBTYPE";
	private static final String SUCCESS = "SUCCESS";

	/**
	 * Creates a new instance of the message object.
	 */
	public Message() {
		jsonobject = new JSONObject();
	}

	/**
	 * Creates a new instance of the message object from the given message.
	 * 
	 * @param JSONString
	 */
	public Message(String JSONString) {
		try {
			jsonobject = new JSONObject(JSONString);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Sets the type of the message.
	 * 
	 * @param MessageType
	 *            the type of the message.
	 */
	public void setMsgType(int MessageType) {
		try {
			jsonobject.put(TYPE, MessageType);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Sets the subtype of the message
	 * 
	 * @param MessageSubType
	 *            The subtype of the message.
	 */
	public void setMsgSubType(int MessageSubType) {
		try {
			jsonobject.put(SUBTYPE, MessageSubType);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Sets the status of the transmission of the request
	 * 
	 * @param success
	 *            <code>true</true> if the request has no errors, <code>false</code>
	 *            otherwise.
	 */
	public void setSuccess(boolean success) {
		try {
			jsonobject.put(SUCCESS, success);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Gets the type of the message.
	 * 
	 * @return The type of the message.
	 */
	public int getMsgType() {
		return getInt(TYPE);
	}

	/**
	 * Gets the subtype of the message.
	 * 
	 * @return The subtype of the message.
	 */
	public int getMsgSubType() {
		return getInt(SUBTYPE);
	}

	/**
	 * Gets the status of the transmission of the request
	 * 
	 * @return <code>true</true> if the request has no errors, <code>false</code>
	 *         otherwise.
	 */
	public boolean getSuccess() {
		return getBoolean(SUCCESS);
	}

	/**
	 * Adds/Sets an attribute of the message.
	 * @param attribute The name of the attribute.
	 * @param value The value of the attribute.
	 */
	public void addAttribute(String attribute, Object value) {
		try {
			jsonobject.put(attribute, value);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Removes an attribute of the message.
	 * @param attribute The name of the attribute.
	 * @return The value of the attribute.
	 */
	public Object removeAttribute(String attribute) {
		return jsonobject.remove(attribute);
	}

	/**
	 * Gets an attribute of the message.
	 * @param attribute The name of the attribute.
	 * @return The value of the attribute.
	 */
	public Object getAttr(String attribute) {
		return jsonobject.opt(attribute);
	}

	/**
	 * Gets a boolean associated with an attribute.
	 * @param key The attribute.
	 * @return The boolean associated with the attribute.
	 */
	public boolean getBoolean(String key) {
		return jsonobject.optBoolean(key);
	}

	/**
	 * Gets an integer associated with an attribute.
	 * @param key The attribute.
	 * @return The integer associated with the attribute.
	 */
	public int getInt(String key) {
		return jsonobject.optInt(key);
	}

	/**
	 * Gets an double associated with an attribute.
	 * @param key The attribute.
	 * @return The double associated with the attribute.
	 */
	public double getDouble(String key) {
		return jsonobject.optDouble(key);
	}

	/**
	 * Gets an long associated with an attribute.
	 * @param key The attribute.
	 * @return The long associated with the attribute.
	 */
	public long getLong(String key) {
		return jsonobject.optLong(key);
	}

	/**
	 * Gets an String associated with an attribute.
	 * @param key The attribute.
	 * @return The String associated with the attribute.
	 */
	public String getString(String key) {
		return jsonobject.optString(key);
	}

	/**
	 * Clears the messsage
	 */
	public void clear() {
		jsonobject = new JSONObject();
	}

	@Override
	public String toString() {
		return jsonobject.toString();
	}

	/**
	 * Sets the message type as an error indicating that the user is not logged in.
	 */
	public void setAsUserNotLoggedIn() {
		this.setMsgType(MSG.USER_NOT_LOGGED_IN);
	}

	public static void main(String[] args) throws JSONException {
		System.out.println("main-Message");
		Message msg = new Message();
		msg.setMsgType(MSG.LOGIN_REQUEST);
		msg.addAttribute("username", "user1");
		// msg.addAttribute("password", "hispa\\sswo[rd]oo" +"\"],hehe\"pppp");
		String d = "az";
		msg.addAttribute("deparse", d);
		msg.addAttribute("age", 312);
		msg.addAttribute("fl", 123.21);
		msg.addAttribute("bool", true);

		String msg1string = msg.toString();

		System.out.println(msg1string);
		System.out.println("out");

		Message reconn = new Message(msg1string);
		System.out.println(reconn.getString("username"));
		// System.out.println( reconn.getInt("password") );
		System.out.println(reconn.getString("deparse"));
		System.out.println(reconn.getInt("age") + reconn.getDouble("fl"));
		System.out.println(reconn.getDouble("fl"));
		System.out.println(reconn.getBoolean("bool") ? "oyeTRUE" : "aww");

		// Message msg2 = new Message();
		//
		// msg2.addAttribute("mess", msg);
		// msg2.addAttribute("2nd", 213.2);
		// System.out.println(msg2.toString());

	}

}
